package rpcerror

import (
	"errors"
	"fmt"
	"sync"

	"hundsun.com/hsl/hschain/common/log/logging"
)

var logger logging.Log
var once sync.Once

//Init 初始化
func Init(log logging.Log) {
	once.Do(func() {
		logger = log
	})
}

//Status Status
type Status struct {
	status  int32
	message string
}

//CommonFail 通用失败
var CommonFail = Status{status: -1, message: "request fail"}

//Success 成功
var Success = Status{status: 0, message: "success"}

//MethodNotFound 方法找不到
var MethodNotFound = Status{status: 1, message: "method not found"}

//WrongParam 参数错误
var WrongParam = Status{status: 2, message: "wrong parameter"}

//SerializeFail 序列化失败
var SerializeFail = Status{status: 3, message: "serialize fail"}

//TxSendFailed 交易发送失败
var TxSendFailed = Status{status: 4, message: "tx send failed"}

//GetPeerCountFailed 获取节点数目失败
var GetPeerCountFailed = Status{status: 5, message: "get peer count failed"}

//GetBlockNumberFailed 获取区块号失败
var GetBlockNumberFailed = Status{status: 6, message: "get block number failed"}

//GetBalanceFailed 获取金额失败
var GetBalanceFailed = Status{status: 7, message: "get balance failed"}

//GetTransactionByHashFailed 查询交易失败
var GetTransactionByHashFailed = Status{status: 8, message: "get transaction by hash failed"}

//GetBlockByNumberFailed 获取区块失败
var GetBlockByNumberFailed = Status{status: 9, message: "get block by number failed"}

//GetExecutedBlockByNumberFailed 获取执行后的区块失败
var GetExecutedBlockByNumberFailed = Status{status: 10, message: "get executed block by number failed"}

//UnsubscribeFailed 取消订阅失败
var UnsubscribeFailed = Status{status: 11, message: "unsubscribe failed"}

//NotExist 不存在
var NotExist = Status{status: 12, message: "empty result"}

//P2pFailed p2p错误
var P2pFailed = Status{status: 13, message: "p2p send message failed"}

//LedgerFailed 账本失败
var LedgerFailed = Status{status: 14, message: "ledger failed"}

//AuthFailed 权限校验失败
var AuthFailed = Status{status: 15, message: "client has no authority"}

//FlowControlFailed 流量控制
var FlowControlFailed = Status{status: 16, message: "request forbidden because flow control"}

//PureMethodFailed 纯查询方法错误
var PureMethodFailed = Status{status: 17, message: "pure call failed"}

//RequestMqMsgFailed mq请求失败
var RequestMqMsgFailed = Status{status: 18, message: "request mq msg failed"}

//GetPeerInfoFailed 获取节点信息失败
var GetPeerInfoFailed = Status{status: 19, message: "get peer info failed"}

//GetIsSyncedFailed 查询节点是否同步失败
var GetIsSyncedFailed = Status{status: 20, message: "get is synced failed"}

//GetContractVersionFailed 查询合约版本号失败
var GetContractVersionFailed = Status{status: 21, message: "get contract version failed"}

//GetPeerIDFailed 查询peerID失败
var GetPeerIDFailed = Status{status: 22, message: "get peer ID failed"}

//IllegalResponse 非法响应
var IllegalResponse = Status{status: 23, message: "illegal response"}

//PeekPendingTxFailed 查询待打包交易失败
var PeekPendingTxFailed = Status{status: 24, message: "peek pending tx failed"}

//TxPoolSizeFailed 查询交易缓存池大小失败
var TxPoolSizeFailed = Status{status: 25, message: "query tx pool size failed"}

//TxPoolHashesFailed 查询待打包交易hash失败
var TxPoolHashesFailed = Status{status: 26, message: "query tx hashes failed"}

// GetBlockExecNumberFailed 获取执行区块高度失败
var GetBlockExecNumberFailed = Status{status: 27, message: "get block execute number failed"}

//GetStatus 获取错误码
func (s *Status) GetStatus() int32 {
	return s.status
}

//GetMessage 获取错误信息
func (s *Status) GetMessage() string {
	return s.message
}

//FormatMsg 错误信息格式化
func (s *Status) FormatMsg(str string) string {
	return fmt.Sprintf("%s:%s", s.GetMessage(), str)
}

//Errorf 打印并返回错误日志
func Errorf(format string, a ...interface{}) error {
	err := fmt.Errorf(format, a...)
	logger.Error(err)
	return err
}

//LoggerErrorf 打印并返回错误日志
func LoggerErrorf(logger logging.Log, format string, a ...interface{}) error {
	err := fmt.Sprintf(format, a...)
	logger.Error(err)
	return errors.New(err)
}
